#pragma once

#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "OSSInfo.generated.h"


/*
* oss 任务类型
*/
UENUM(BlueprintType, Category = "AliyunOss")
enum class EAliyunOssType : uint8
{
	//下载对象
	DownloadByObject = 0,
	//上传对象
	UploadByObject,
	//上传字符串
	UploadStringBuffer,
};

USTRUCT(BlueprintType, Category = "AliyunOss")
struct FOssOssClientInfo
{
	GENERATED_USTRUCT_BODY()

	UPROPERTY(BlueprintReadWrite, Category = "AliyunOss")
		FString AccessKeyId;

	UPROPERTY(BlueprintReadWrite, Category = "AliyunOss")
		FString AccessKeySecret;

	UPROPERTY(BlueprintReadWrite, Category = "AliyunOss")
		FString Endpoint;

	FOssOssClientInfo()
		:AccessKeyId(), AccessKeySecret(), Endpoint()
	{

	}

	FOssOssClientInfo(
		const FString& accessKeyId, const FString& accessKeySecret, const FString& endpoint)
		:AccessKeyId(accessKeyId), AccessKeySecret(accessKeySecret), Endpoint(endpoint)
	{

	}


	bool IsValid()const
	{
		if (AccessKeyId.IsEmpty()
			|| AccessKeySecret.IsEmpty()
			|| Endpoint.IsEmpty())
		{
			return false;
		}
		return true;
	}

};



/*
* OSS 任务描述文件
* 
*/
USTRUCT(BlueprintType, Category = "AliyunOss")
struct ALIYUNCPPPLUGIN_API FAliyunOssTaskInfo
{
	GENERATED_USTRUCT_BODY()
private:
	bool useBucketNameAndKey = true;
public:
	//任务类型
	UPROPERTY(BlueprintReadOnly, Category = "AliyunOss")
		EAliyunOssType handleType;
	
	//任务bucketName
	UPROPERTY(BlueprintReadOnly, Category = "AliyunOss")
		FString bucketName;

	//任务objectKey
	UPROPERTY(BlueprintReadOnly, Category = "AliyunOss")
		FString objectKey;

	//任务下载完整地址
	UPROPERTY(BlueprintReadOnly, Category = "AliyunOss")
		FString inOssObjectFilePath;

	//要上传的字符串 只有EAliyunOssType = UploadStringBuffer 时有意义
	UPROPERTY(BlueprintReadWrite, Category = "AliyunOss")
		FString strLocalObjectFilePath;

	//任务数据缓存   最大只有16GB
	TArray<uint8>* LocalObjectDataPtr;

	FAliyunOssTaskInfo() 
	{

	}

	
	/*
	* 从bucket和 objectKey构造一个任务必须指定缓存数据LocalBuffer
	*/
	FAliyunOssTaskInfo(const EAliyunOssType& type, const FString& bucket, const FString& key
		,TArray<uint8>* LocalBuffer);

	/*
	* 从url构造一个任务必须指定缓存数据LocalBuffer
	*/
	FAliyunOssTaskInfo(const EAliyunOssType& type, const FString& completefilePath
		, TArray<uint8>* LocalBuffer);

	///*
	//* 从url构造一个任务必须指定缓存数据LocalBuffer
	//*/
	//FAliyunOssTaskInfo(const EAliyunOssType& type, const FString& bucket, const FString& key
	//	, const FString& completefilePath, TArray<uint8>* LocalBuffer);

	//从bucket和 objectKey构造一个任务,数据优先储存到硬盘
	FAliyunOssTaskInfo(const EAliyunOssType& type, const FString& bucket, const FString& key
		, const FString& LocalObjectFilePath);

	//从url构造一个任务,数据优先储存到硬盘
	FAliyunOssTaskInfo(const EAliyunOssType& type, const FString& completefilePath
		, const FString& LocalObjectFilePath);


	FAliyunOssTaskInfo(const EAliyunOssType& type, const FString& bucket, const FString& key
		, const FString& completefilePath, const FString& LocalObjectFilePath);

	//build EAliyunOssType::UploadBufferData taskinfo
	FAliyunOssTaskInfo(const FString& bucket, const FString& key, const FString& completefilePath, const FString& InContentData);

	bool UseBucketNameAndKey()const;

	bool IsValid()const;

	FString GetOssObjPath()const;


	static FString TransformationPath(const FString& path);

	static bool TransformationPathToBucketAndKey(const FString& path, FString& Bucket,  FString& key);

};


DECLARE_DELEGATE_TwoParams(FAliOssOnComplete, bool, void*);
DECLARE_DELEGATE_ThreeParams(FAliOssOnCompleteWithMsg, bool, void*, FString);
DECLARE_DELEGATE_TwoParams(FAliOssOnProgress, float, void*);

DECLARE_DELEGATE(FSTGraphTasksBatchOnComplete);

struct ALIYUNCPPPLUGIN_API FOssCallBackFunction
{

	FAliOssOnComplete onComplete;
	FAliOssOnCompleteWithMsg onCompleteWithMsg;
	FAliOssOnProgress onProgress;

	void CallOnProgress(float fPercent, void* userData)const;
	void CallOnComplete(bool isSuccess,void* userData,const FString& msg)const;
	void CallOnComplete(bool isSuccess, void* userData)const;

};

struct ALIYUNCPPPLUGIN_API FOssTimeTakeNotes
{
	//Packet unit is  B;
	int64 dataSize;
	FDateTime buildTime;
	FDateTime startTime;
	FDateTime completeTime;
	//transmission speed   Mb/s
	float loadSeep;

	FOssTimeTakeNotes();
	//size unit is  B;
	void StartWork(int64 size = 0);
	//size unit is  B;
	void CompleteWork(int64 size = 0);

	float GetSizeUintMb()const;

	FString ToString()const;

};